package com.applet.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.applet.common.constant.JwtClaimsConstant;
import com.applet.common.constant.MessageConstant;
import com.applet.common.constant.StateConstant;
import com.applet.common.context.BaseContext;
import com.applet.common.exection.LoginFailedException;
import com.applet.common.properties.JwtProperties;
import com.applet.common.properties.WeChatProperties;
import com.applet.common.utils.HttpClientUtil;
import com.applet.common.utils.JwtUtil;
import com.applet.common.utils.WxUtil;
import com.applet.common.vo.UserLoginVO;
import com.applet.mapper.UserMapper;
import com.applet.pojo.dto.UserInfoDTO;
import com.applet.pojo.dto.UserLoginDTO;
import com.applet.pojo.entity.User;
import com.applet.pojo.vo.UserInfoVO;
import com.applet.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;

/**
 * @author “XuShao”
 * @date 2024/12/16 19:24
 * @description
 */
@Service
public class UserServiceImpl implements UserService {
    // 微信服务接口地址
    public static final String WX_LOGIN = "https://api.weixin.qq.com/sns/jscode2session";
    private static final Logger log = LoggerFactory.getLogger(UserServiceImpl.class);

    public static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token";
    public static final String ACCESS_TOKEN_Phone_Url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber";

//    public static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential";
//    public static final String ACCESS_TOKEN_Phone_Url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber";

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private JwtProperties jwtProperties;

    @Autowired
    private WeChatProperties weChatProperties;


    @Override
    public UserLoginVO wxLogin(UserLoginDTO userLoginDTO) throws IOException {
        String wxCode = userLoginDTO.getWxCode();

        String accessToken = WxUtil.getAccessToken(weChatProperties.getAppid(), weChatProperties.getSecret());

        // 2. 获取手机号信息
        String phone = WxUtil.getPhoneNumber(accessToken, wxCode);
        // 2. 获取openid
        String openId = getOpenid(userLoginDTO.getOpenIdCode());

        log.info("phone：{}", phone);
        log.info("openId：{}", openId);


        // 判断openid是否为空，如果为空表示登录失败，抛出业务异常
        if(phone == null){
            throw new LoginFailedException(MessageConstant.LOGIN_FAILED);
        }

        // 判断当前用户是否为新用户
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getPhone, phone));

        log.info("用户user：{}", user);

        // 如果是新用户，自动完成注册
        if(user == null) {
            User newUser = new User();
            newUser.setName("微信用户");
            newUser.setPhone(phone);
            newUser.setJurisdiction(User.PERM_0);
            newUser.setDeleted(StateConstant.ENABLE);
            newUser.setOpenid(openId);
            newUser.setCreateTime(LocalDateTime.now());
            newUser.setUpdateTime(LocalDateTime.now());

            userMapper.insert(newUser);
        }

        Map<String, Object> claims = new HashMap<>();
//        assert user != null;
        claims.put(JwtClaimsConstant.VOLUNTEER_ID, user.getId());
        claims.put(JwtClaimsConstant.PERM, user.getJurisdiction());
        String token = JwtUtil.createJWT(jwtProperties.getSecretKey(), jwtProperties.getTtl(), claims);

        return UserLoginVO.builder()
                .id(user.getId())
                .openid(openId)
                .token(token)
                .build();
    }

    @Override
    public void update(UserInfoDTO userInfoDTO) {
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getId, BaseContext.getCurrentId()));

        BeanUtils.copyProperties(userInfoDTO, user);

        userMapper.updateById(user);
    }

    @Override
    public UserInfoVO getUserInfo() {
        User user = userMapper.selectById(BaseContext.getCurrentId());
        UserInfoVO userInfoVO = new UserInfoVO();
        BeanUtils.copyProperties(user, userInfoVO);
        return userInfoVO;
    }

    // 通过code获取手机号
    private Object getPassCodePhone(String wxCode) throws IOException {
        // 1. 先获取access_token
        // 调用微信接口服务，获得当前微信用户的openid
        Map<String, String> aT = new HashMap<>();
        aT.put("appid",weChatProperties.getAppid());
        aT.put("secret",weChatProperties.getSecret());
        aT.put("grant_type","client_credential");
        Object accessToken = HttpClientUtil.doGet(ACCESS_TOKEN_URL, aT);
        log.info("accessToken：{}", accessToken);



        // 2. 拿到获取接口调用凭据，进行获取手机号信息
        // 手机号验证
        HashMap<String, String> aTPhone = new HashMap<>();
        aTPhone.put("access_token", "1111");
        aTPhone.put("wxCode", wxCode);
        Object phoneInfo = HttpClientUtil.doPost(ACCESS_TOKEN_Phone_Url, aTPhone);
        log.info("phoneInfo：{}", phoneInfo);


//        HashMap<String, String> object = new HashMap<>();
//        object.put("")

        return phoneInfo;
    }

    private String getOpenid(String code){
        // 调用微信接口服务，获得当前微信用户的openid
        Map<String, String> map = new HashMap<>();
        map.put("appid",weChatProperties.getAppid());
        map.put("secret",weChatProperties.getSecret());
        map.put("js_code",code);
        map.put("grant_type","authorization_code");
        String json = HttpClientUtil.doGet(WX_LOGIN, map);

        JSONObject jsonObject = JSON.parseObject(json);
        return jsonObject.getString("openid");
    }
}
